package com.hnchances.studentscoresystem.util;

import lombok.extern.slf4j.Slf4j;

import java.util.regex.Pattern;

/**
 * 参数校验工具类
 * 功能：通用参数合法性校验（非空、格式、长度等）
 * 对应文档需求：确保接口入参符合业务规则（如手机号11位、身份证合法）
 */
@Slf4j
public class ValidationUtil {

    /**
     * 手机号正则（中国大陆11位手机号，支持13/14/15/17/18/19开头）
     */
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");

    /**
     * 身份证号正则（18位，支持最后一位为X）
     */
    private static final Pattern ID_CARD_PATTERN = Pattern.compile("^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");

    /**
     * 非空校验（字符串）
     * @param str 待校验字符串
     * @param fieldName 字段名称（用于异常提示，如“用户名”）
     * @throws IllegalArgumentException 字段为空时抛出
     */
    public static void checkNotNull(String str, String fieldName) {
        if (str == null || str.trim().isEmpty()) {
            log.warn("参数校验失败：{}不能为空", fieldName);
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
    }

    /**
     * 非空校验（数字）
     * @param num 待校验数字
     * @param fieldName 字段名称（用于异常提示，如“班级ID”）
     * @throws IllegalArgumentException 数字为null时抛出
     */
    public static void checkNotNull(Number num, String fieldName) {
        if (num == null) {
            log.warn("参数校验失败：{}不能为空", fieldName);
            throw new IllegalArgumentException(fieldName + "不能为空");
        }
    }

    /**
     * 手机号格式校验
     * @param phone 待校验手机号
     * @throws IllegalArgumentException 格式不合法时抛出
     */
    public static void checkPhoneFormat(String phone) {
        checkNotNull(phone, "手机号");
        if (!PHONE_PATTERN.matcher(phone).matches()) {
            log.warn("参数校验失败：手机号格式不合法，phone: {}", phone);
            throw new IllegalArgumentException("手机号格式不合法（需为11位中国大陆手机号）");
        }
    }

    /**
     * 身份证号格式校验（18位）
     * @param idCard 待校验身份证号
     * @throws IllegalArgumentException 格式不合法时抛出
     */
    public static void checkIdCardFormat(String idCard) {
        checkNotNull(idCard, "身份证号");
        if (!ID_CARD_PATTERN.matcher(idCard).matches()) {
            log.warn("参数校验失败：身份证号格式不合法，idCard: {}", idCard.substring(0, 6) + "***********");
            throw new IllegalArgumentException("身份证号格式不合法（需为18位有效身份证号）");
        }
    }

    /**
     * 字符串长度校验（最小长度<=长度<=最大长度）
     * @param str 待校验字符串
     * @param fieldName 字段名称（如“用户名”）
     * @param minLen 最小长度
     * @param maxLen 最大长度
     * @throws IllegalArgumentException 长度不合法时抛出
     */
    public static void checkStrLength(String str, String fieldName, int minLen, int maxLen) {
        checkNotNull(str, fieldName);
        int length = str.trim().length();
        if (length < minLen || length > maxLen) {
            log.warn("参数校验失败：{}长度不合法，当前长度: {}, 要求: {}-{}", fieldName, length, minLen, maxLen);
            throw new IllegalArgumentException(fieldName + "长度需在" + minLen + "-" + maxLen + "位之间");
        }
    }

    /**
     * 数字范围校验（最小值<=数字<=最大值）
     * @param num 待校验数字
     * @param fieldName 字段名称（如“成绩”）
     * @param min 最小值
     * @param max 最大值
     * @throws IllegalArgumentException 范围不合法时抛出
     */
    public static void checkNumRange(Number num, String fieldName, Number min, Number max) {
        checkNotNull(num, fieldName);
        double numVal = num.doubleValue();
        double minVal = min.doubleValue();
        double maxVal = max.doubleValue();
        if (numVal < minVal || numVal > maxVal) {
            log.warn("参数校验失败：{}范围不合法，当前值: {}, 要求: {}-{}", fieldName, numVal, minVal, maxVal);
            throw new IllegalArgumentException(fieldName + "需在" + minVal + "-" + maxVal + "范围内");
        }
    }
}